package com.basic.webframe;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.basic.common.FuncArray;
import com.basic.common.FuncFile;
import com.basic.common.FuncStatic;
import com.basic.webframe.ij.IjHttpServletRequest;
import com.basic.webframe.ij.IjHttpServletResponse;
import com.basic.webframe.ij.IjParamInt;
import com.basic.webframe.ij.IjParamStrArray;
import com.basic.webframe.ij.IjParamString;

public abstract class HttpFilter implements Filter {
	private static Logger logger = Logger.getLogger ( HttpFilter.class.getName () );
	protected static HashMap<String, Class> actionList = new HashMap<String, Class>();
 	public void init(FilterConfig config) throws ServletException {
		try {
			  
			Set<Class<?>> set = FuncFile.getClasses(webFolder() + ".control");
			for (Class c : set) {
				String p = c.getName();
				String key = p
						.substring(p.indexOf(".control.") + 8, p.length());
				actionList.put(key.toLowerCase().replace('.', '/'), c);
			}
		} catch (Exception e) {
			logger.error(FuncStatic.errorTrace(e));
		}
	}
	
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) {
		try {
			request.setCharacterEncoding("UTF-8");
			response.setCharacterEncoding(projectEncode());
			response.setContentType("text/html; charset=" + projectEncode());
			process((HttpServletRequest)request,(HttpServletResponse)response);
 		} catch (Exception ioe) {
			logger.error(FuncStatic.errorTrace(ioe));
		}
	}

	public abstract String projectEncode();
	public abstract String webFolder();
	public abstract String host();
	/**
	 * 页面显示之前执行,如果返回FALSE，则不执行页面函数
	 * @return
	 */
	public abstract boolean ifGoRender(HttpServletRequest request,
			HttpServletResponse response,Object controlObject,String funcName);
	public void destroy() {
	}
	
	private void process(HttpServletRequest request, HttpServletResponse response){
		String nowURI = request.getRequestURI();
		try {
			long start = System.currentTimeMillis();
			String className = nowURI.substring( host().length(), nowURI.indexOf(".")).toLowerCase(); 
			Object o = null;
			try {
				 o = HttpFilter.actionList.get(className).newInstance(); 
			} catch (Exception e) {
				logger.info("not found action class:" + nowURI); 
				response.getWriter().write("<h1>404  ，NOT FIND PAGE!</h1>");
				return ;
			}  
			String funcName = "func";
			if (request.getParameter("domethod") != null) {
				funcName = request.getParameter("domethod");
			}
			
			if(!ifGoRender(request,response,o,funcName )){
				return ;
			}
			Field[] file = o.getClass().getFields();
			for (int i = 0; i < file.length; i++) {
				Field f = file[i];
				String fieldName = f.getName();
				if (f.isAnnotationPresent(IjParamString.class)){
					
					if ( request.getParameter(fieldName) != null) {
						f.set(o, request.getParameter(fieldName));
					}
				}
				else if (f.isAnnotationPresent(IjParamInt.class)) {
					try {
						if (!FuncStatic.checkIsEmpty(request.getParameter(fieldName))  ) {
							f.set(o, Integer.parseInt(request
									.getParameter(fieldName)));
						}
					} catch (Exception e) {
					}
				} 
				else if (f.isAnnotationPresent(IjParamStrArray.class)) {
					if (request.getParameterValues(fieldName) != null){  
 						f.set(o, FuncArray.linkArray(request.getParameterValues(fieldName), ",") );
					}
				}
				else if (f.isAnnotationPresent(IjHttpServletResponse.class))
					f.set(o, response);
				else if (f.isAnnotationPresent(IjHttpServletRequest.class)){
					f.set(o, request);
				}
			}
			Method m = null;
			m = o.getClass().getMethod(funcName);
			String restr = (String) m.invoke(o);
			if (restr != null)
				response.getWriter().write(restr);
			 
			logger.info("page run time(ms):"
					+ (System.currentTimeMillis() - start) + " =>" + nowURI);

		} catch (Exception e) {
			logger.error(FuncStatic.errorTrace(e));
		}
	}
}

 